ia64_rr vrr;
u64 pval;
u64 vhpt_offset;
+ u64 mask;
+
vpta.val = vmx_vcpu_get_pta(vcpu);
vcpu_get_rr(vcpu, vadr, &vrr.rrval);
- if(vpta.vf){
- pval = ia64_call_vsa(PAL_VPS_THASH, vadr, vrr.rrval,
- vpta.val, 0, 0, 0, 0);
- pval = vpta.val & ~0xffff;
- }else{
- vhpt_offset=((vadr>>vrr.ps)<<3)&((1UL<<(vpta.size))-1);
+ mask = (1UL << vpta.size) - 1;
+ if (vpta.vf) {
+ vadr = (vadr & 0x1fffffffffffffffUL) >> vrr.ps;
+ vhpt_offset = vadr ^ vrr.rid;
+ pval = (vpta.val & ~0x7fffUL) + ((vhpt_offset << 5) & mask);
+ } else {
+ vhpt_offset=((vadr >> vrr.ps) << 3) & mask;
pval = (vadr & VRN_MASK) |
- (vpta.val<<3>>(vpta.size+3)<<(vpta.size))|
+ (vpta.val << 3 >> (vpta.size + 3) << vpta.size) |
vhpt_offset;
}
return pval;
ia64_rr vrr;
PTA vpta;
u64 pval;
+ u64 rid;
vpta.val = vmx_vcpu_get_pta(vcpu);
vcpu_get_rr(vcpu, vadr, &vrr.rrval);
if(vpta.vf){
- pval = ia64_call_vsa(PAL_VPS_TTAG, vadr, vrr.rrval, 0, 0, 0, 0, 0);
+ vadr = (vadr & 0x1fffffffffffffffUL) >> vrr.ps;
+ rid = vrr.rid;
+ pval = vadr ^ (rid << 39);
}else{
pval = 1;
}
REGS *regs;
u64 vhpt_adr, madr;
IA64_PSR vpsr;
- regs=vcpu_regs(vcpu);
- pt_isr.val=VMX(vcpu,cr_isr);
- visr.val=0;
- visr.ei=pt_isr.ei;
- visr.ir=pt_isr.ir;
+
+ regs = vcpu_regs(vcpu);
+ pt_isr.val = VMX(vcpu, cr_isr);
+ visr.val = 0;
+ visr.ei = pt_isr.ei;
+ visr.ir = pt_isr.ir;
vpsr.val = VCPU(vcpu, vpsr);
- visr.na=1;
+ visr.na = 1;
+
+ /* First look in VTLB. */
data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
- if(data){
- if(data->p==0){
+ if (data) {
+ if (data->p == 0) {
vcpu_set_isr(vcpu,visr.val);
data_page_not_present(vcpu, vadr);
return IA64_FAULT;
- }else if(data->ma == VA_MATTR_NATPAGE){
+ } else if (data->ma == VA_MATTR_NATPAGE) {
vcpu_set_isr(vcpu, visr.val);
dnat_page_consumption(vcpu, vadr);
return IA64_FAULT;
- }else{
+ } else {
*padr = ((data->ppn >> (data->ps - 12)) << data->ps) |
(vadr & (PSIZE(data->ps) - 1));
return IA64_NO_FAULT;
}
}
+
+ /* Look in mVHPT. */
data = vhpt_lookup(vadr);
- if(data){
- if(data->p==0){
+ if (data) {
+ if (data->p == 0) {
vcpu_set_isr(vcpu,visr.val);
data_page_not_present(vcpu, vadr);
return IA64_FAULT;
- }else if(data->ma == VA_MATTR_NATPAGE){
+ } else if (data->ma == VA_MATTR_NATPAGE) {
vcpu_set_isr(vcpu, visr.val);
dnat_page_consumption(vcpu, vadr);
return IA64_FAULT;
- }else{
+ } else {
madr = (data->ppn >> (data->ps - 12) << data->ps) |
(vadr & (PSIZE(data->ps) - 1));
*padr = __mpa_to_gpa(madr);
return IA64_NO_FAULT;
}
}
- else{
- if(!vhpt_enabled(vcpu, vadr, NA_REF)){
- if(vpsr.ic){
- vcpu_set_isr(vcpu, visr.val);
- alt_dtlb(vcpu, vadr);
- return IA64_FAULT;
- }
- else{
- nested_dtlb(vcpu);
- return IA64_FAULT;
- }
+
+ /* If VHPT is not enabled, inject fault. */
+ if (!vhpt_enabled(vcpu, vadr, NA_REF)) {
+ if (vpsr.ic) {
+ vcpu_set_isr(vcpu, visr.val);
+ alt_dtlb(vcpu, vadr);
+ return IA64_FAULT;
+ } else {
+ nested_dtlb(vcpu);
+ return IA64_FAULT;
}
- else{
- vhpt_adr = vmx_vcpu_thash(vcpu, vadr);
- data = vtlb_lookup(vcpu, vhpt_adr, DSIDE_TLB);
- if(data){
- if(vpsr.ic){
- vcpu_set_isr(vcpu, visr.val);
- dtlb_fault(vcpu, vadr);
- return IA64_FAULT;
- }
- else{
- nested_dtlb(vcpu);
- return IA64_FAULT;
- }
- }
- else{
- if(vpsr.ic){
- vcpu_set_isr(vcpu, visr.val);
- dvhpt_fault(vcpu, vadr);
- return IA64_FAULT;
- }
- else{
- nested_dtlb(vcpu);
- return IA64_FAULT;
- }
- }
+ }
+
+ /* Get gVHPT entry. */
+ vhpt_adr = vmx_vcpu_thash(vcpu, vadr);
+ data = vtlb_lookup(vcpu, vhpt_adr, DSIDE_TLB);
+ if (data) {
+ /* FIXME: we should read gadr from the entry! */
+ if (vpsr.ic) {
+ vcpu_set_isr(vcpu, visr.val);
+ dtlb_fault(vcpu, vadr);
+ return IA64_FAULT;
+ } else {
+ nested_dtlb(vcpu);
+ return IA64_FAULT;
+ }
+ } else {
+ if (vpsr.ic) {
+ vcpu_set_isr(vcpu, visr.val);
+ dvhpt_fault(vcpu, vadr);
+ return IA64_FAULT;
+ } else {
+ nested_dtlb(vcpu);
+ return IA64_FAULT;
}
}
}
return key;
}
- /* FIXME: if psr.dt is set, look in the guest VHPT. */
data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
- if (!data || !data->p)
- key = 1;
- else
- key = data->key << 8;
+ if (data) {
+ if (data->p)
+ return data->key << 8;
+ else
+ return 1;
+ }
+
+ data = vhpt_lookup(vadr);
+ if (data) {
+ if (data->p)
+ return data->key << 8; /* FIXME: possible mangling/masking. */
+ else
+ return 1;
+ }
+
+ if (!vhpt_enabled(vcpu, vadr, NA_REF))
+ return 1;
- return key;
+ /* FIXME: look in the guest VHPT. */
+ return 1;
}